﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;
using System.Web;
using MLBService.Model;
using System.ComponentModel;
using MLBService.Resources;
using MLBService.Interfaces;
using System.ServiceModel.Syndication;
using System.Net;

namespace MLBService
{
    // Start the service and browse to http://localhost:51985/mlb/help to view the service's generated help page
    // NOTE: By default, a new instance of the service is created for each call; change the 
    //InstanceContextMode to Single if you want a single instance of the service to process all calls.
	
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class MlbService : IMlb
    {

        #region Helper methods

        private static void useCache(){
            WebOperationContext.Current.OutgoingResponse.Headers.Add("Last-Modified", "Mon, 21 Nov 2008 01:03:33 GMT");
        }

        private static OutgoingWebResponseContext resp()
        {
            return WebOperationContext.Current.OutgoingResponse;
        }

        private static int paramToInt(string param)
        {
            try
            {
                return Convert.ToInt32(param);
            }
            catch
            {
                resp().StatusCode = HttpStatusCode.BadRequest;
                throw;
            }
        }

        #endregion

        public void AddFranchise(FranchiseItem franchise)
        {
            using (fourseamEntities context = new fourseamEntities())
            {
                //!!! This is an idempotent method - decide how to check for the existence based on your data
                var exists = (from f in context.Franchises
                              where f.FranchiseDesignator == franchise.Designator
                              select f).FirstOrDefault();
                if (exists == null)
                {
                    context.Franchises.AddObject(new Franchise()
                    {
                        FranchiseDesignator = franchise.Designator,
                        FranchiseName = franchise.Name,
                        IsActive = franchise.IsActive,
                        LastUpdate = DateTime.Now
                    });
                    context.SaveChanges();
                }
            }
        }

        public void DeleteFranchise(string franchiseId)
        {
            int fid = paramToInt(franchiseId);
            using (fourseamEntities context = new fourseamEntities())
            {
                var franchise = (from f in context.Franchises
                                 where f.FranchiseId == fid
                                 select f).FirstOrDefault();
                if (franchise != null)
                {
                    context.Franchises.DeleteObject(franchise);
                    context.SaveChanges();
                }
            }
        }

        public void AddTeam(string franchiseId)
        {
            throw new NotImplementedException();
        }

        public FranchiseList GetCurrentFranchises()
        {
            useCache();
            return new FranchiseList().LoadCurrent();
        }

        public FranchiseList GetAllFranchises()
        {
            useCache();
            return new FranchiseList().LoadAll();
        }

        public TeamList GetTeamsByYear(string year)
        {
            useCache();
            try
            {
                return new TeamList().Load(paramToInt(year));
            }
            catch
            {
                return null;
            }
        }

        public FranchiseItem GetFranchiseById(string franchiseid)
        {
            useCache();
            //!!! This is really duplicated in teams/{franchiseid}
            try
            {
                return new FranchiseItem().Load(paramToInt(franchiseid));
            }
            catch
            {
                return null;
            }
        }

        public FranchiseItem GetTeamsByFranchiseId(string franchiseid)
        {
            useCache();
            try
            {
                return new FranchiseItem().Load(paramToInt(franchiseid));
            }
            catch
            {
                return null;
            }
        }

        public TeamItem GetTeamByTeamId(string teamid)
        {
            useCache();
            try
            {
                return new TeamItem().Load(paramToInt(teamid));
            }
            catch
            {
                return null;
            }
        }

        public PlayerList GetPlayersByTeamId(string teamid)
        {
            useCache();
            try
            {
                return new PlayerList().Load(paramToInt(teamid));
            }
            catch
            {
                return null;
            }
        }

        public PlayerItem GetPlayerByPlayerId(string playerid)
        {
            useCache();
            try
            {
                return new PlayerItem().Load(paramToInt(playerid));
            }
            catch
            {
                return null;
            }
        }

        public BattingStatsItem GetYearlyBattingStatsForPlayer(string playerid, string year)
        {
            useCache();
            try
            {
                return new BattingStatsItem().Load(paramToInt(playerid), paramToInt(year));
            }
            catch
            {
                return null;
            }
        }

        public FieldingStatsItem GetYearlyFieldingStatsForPlayer(string playerid, string year)
        {
            useCache();
            try
            {
                return new FieldingStatsItem().Load(paramToInt(playerid), paramToInt(year));
            }
            catch
            {
                return null;
            }
        }

        public PitchingStatsItem GetYearlyPitchingStatsForPlayer(string playerid, string year)
        {
            useCache();
            try
            {
                return new PitchingStatsItem().Load(paramToInt(playerid), paramToInt(year));
            }
            catch
            {
                return null;
            }
        }

        public CareerBattingStatsList GetCareerBattingStatsForPlayer(string playerid)
        {
            useCache();
            try
            {
                return new CareerBattingStatsList().Load(paramToInt(playerid));
            }
            catch
            {
                return null;
            }
        }

        public CareerFieldingStatsList GetCareerFieldingStatsForPlayer(string playerid)
        {
            useCache();
            try
            {
                return new CareerFieldingStatsList().Load(paramToInt(playerid));
            }
            catch
            {
                return null;
            }
        }

        public CareerPitchingStatsList GetCareerPitchingStatsForPlayer(string playerid)
        {
            useCache();
            try
            {
                return new CareerPitchingStatsList().Load(paramToInt(playerid));
            }
            catch
            {
                return null;
            }
        }

        public System.ServiceModel.Syndication.SyndicationFeedFormatter GetFranchiseFeed()
        {
            FranchiseList currentFranchises = new FranchiseList().LoadCurrent();
            SyndicationFeed feed = new SyndicationFeed("Current franchises", 
                "A list of current franchises... Man - who saw that coming??", 
                new Uri("http://localhost/mlb/franchisefeed"));
            feed.Authors.Add(new SyndicationPerson("tim.swords@hotmail.com"));
            feed.Categories.Add(new SyndicationCategory("Baseball, baseball, and other various medical topics"));
            feed.Description = new TextSyndicationContent("If you can't figure out what this feed's about, then... well...");            

            List<SyndicationItem> items = new List<SyndicationItem>();

            foreach (UriLink link in currentFranchises.Franchises)
            {
                SyndicationItem item1 = new SyndicationItem(
                    link.GetFriendlyDescription(),
                    "Some potential information about this franchis...",
                    new Uri(link.Uri),
                    Guid.NewGuid().ToString(),
                    DateTime.Now);                
                items.Add(item1);
            }

            feed.Items = items;
            //return new Atom10FeedFormatter(feed);
            return new Rss20FeedFormatter(feed);
        }
    }
}
